package com.apobates.forum.orize;

import com.apobates.forum.orize.core.OrizeMember;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
import java.util.function.BiPredicate;

/**
 * 验证结果对象
 * @author xiaofanku@live.cn
 * @since 20210822
 */
public final class OrizeMatchResult {
    //请求待验证的表达式
    private final OrizeExpression expression;
    //资源,在未找到资源时为null
    private final OrizeResource resource;
    //错误消息
    private final String message;
    private final static String OK = "ok";
    private final static String PASS = "ps"; //验证地址时放行
    private final static String NEXT = "nt"; //验证地址通过后下一步验证角色
    private final static Logger logger = LoggerFactory.getLogger(OrizeMatchResult.class); //查找过程结果

    private OrizeMatchResult(OrizeExpression expression, OrizeResource resource, String message) {
        this.expression = expression;
        this.resource = resource;
        this.message = message;
    }

    public OrizeExpression getExpression() {
        return expression;
    }

    public OrizeResource getResource() {
        return resource;
    }

    public String getMessage() {
        return message;
    }

    /**
     * 使用谓词表达式来验证OrizeMember
     *
     * @param member OrizeMember
     * @param memberPredicate 验证OrizeMember的谓词表达式
     * @return
     */
    public Optional<OrizeMatchResult> check(final OrizeMember member, BiPredicate<OrizeMember,String[]> memberPredicate){
        if(!NEXT.equals(getMessage()) || null == resource){ //不是合法渠道进入
            return Optional.ofNullable(this);
        }
        String _msg = "当前用户不满足角色需求";
        String[] _roles = getResource().getRoles().split(",");
        if(memberPredicate.test(member, _roles)){
            _msg = OK;
        }
        return Optional.ofNullable(new OrizeMatchResult(getExpression(), getResource(), _msg));
    }

    /**
     * 验证结果是否表示成功了
     * @return true表示成功,false表示失败
     */
    public boolean isCheckSuccess(){
        return OK.equals(getMessage()) || PASS.equals(getMessage());
    }

    /**
     * 第一阶段结果构造
     */
    public static class Builder{
        private OrizeExpression expression;

        public Builder(OrizeExpression expression){
            this.expression = expression;
        }

        /**
         * 验证地址通过后下一步验证角色
         * @param resource
         * @return
         */
        public OrizeMatchResult next(OrizeResource resource){
            return new OrizeMatchResult(expression, resource, NEXT);
        }

        /**
         * 匹配地址时出错了
         * @param exceptionMessage
         * @return
         */
        public OrizeMatchResult error(String exceptionMessage){
            return new OrizeMatchResult(expression, null, exceptionMessage);
        }


        /**
         * 匹配地址时放行
         * @return
         */
        public OrizeMatchResult pass(){
            return new OrizeMatchResult(expression, null, PASS);
        }
    }
}
